﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Aribaccio.Office
{
    public class OfficerCsv : IOfficer
    {
        /// <summary>
        /// 写入原表数据量超过此分批量，进行分批追加写入，提高写入的性能
        /// </summary>
        private int BatchSize = 5000;
        /// <summary>
        /// 拼接的分隔符，默认逗号设置分隔
        /// </summary>
        private string Separator = ",";

        /// <summary>
        /// 对保存文件名称的判断，不可包含特殊字符
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public bool CheckNameQuota(string str)
        {
            bool isOk = true;
            string result = str;
            string[] strQuota = { "~", "\\", "@", "$", "%", "^", "`", ":", "*", "/", "<", ">", "?", "_", "&" }; //"*", "/","#",  "(", ")", 
            for (int i = 0; i < strQuota.Length; i++)
            {
                if (result.IndexOf(strQuota[i]) > -1) isOk = false;
            }
            return isOk;
        }
        /// <summary>
        /// 读取列名数据集合
        /// </summary>
        /// <param name="argFilePathName">CSV文件全路径</param>
        /// <param name="argIsIdenticalSheet">是否是相同Process的Recipe</param>
        /// <returns>返回读取CSV数据列名集合</returns>
        public Task<ResultList<OfficeFileDataReadColumn>> ReadDataTableColumns(string argFilePathName, bool argIsIdenticalSheet = false)
        {
            return Task.Run(() =>
            {
                ResultList<OfficeFileDataReadColumn> ResultColumns = new ResultList<OfficeFileDataReadColumn>();
                Stopwatch swatch = new Stopwatch();
                swatch.Start();
                try
                {
                    //读取文件数据，写入头部列名
                    using (FileStream fileStream = new FileStream(argFilePathName, FileMode.Open, FileAccess.Read))
                    {
                        StreamReader streamReader = new StreamReader(fileStream, Encoding.UTF8);
                        //记录读取的第一行记录头部列名
                        string[] strLines = streamReader.ReadLine()?.Split(',');
                        //记录头部列名各字段内容
                        if (strLines != null && strLines.Length > 0)
                        {
                            ResultColumns.Data.Add(new OfficeFileDataReadColumn(0) { SheetColumns = strLines.ToList() });
                        }
                        streamReader.Close();
                        fileStream.Close();
                    }
                }
                catch (Exception ep)
                {
                    ResultColumns.ResultCode = ResultStatus.Exception;
                    ResultColumns.ResultMsg = "Exception Message：" + ep.Message;
                }
                finally
                {
                    swatch.Stop();
                    ResultColumns.ResultMilliseconds = swatch.ElapsedMilliseconds;
                }
                return ResultColumns;
            });
        }
        /// <summary>
        /// 读取列名和列值数据[CSV文件到DataTable]
        /// </summary>
        /// <param name="argFilePathName">CSV文件全路径</param>
        /// <param name="argIsExistsColumns">是否存在头部列名行数据</param>
        /// <param name="argIsIdenticalSheet">是否是相同Process的Recipe</param>
        /// <returns>返回读取CSV数据的DataTable</returns>
        public Task<ResultList<OfficeFileDataReadTable>> ReadDataTable(string argFilePathName, bool argIsExistsColumns = true, bool argIsIdenticalSheet = false)
        {
            return Task.Run(() =>
            {
                ResultList<OfficeFileDataReadTable> ResultDataTable = new ResultList<OfficeFileDataReadTable>();
                Stopwatch swatch = new Stopwatch();
                swatch.Start();
                try
                {
                    //标示第一行列名是否已读取
                    bool bIsColumnReader = false;
                    //标示列数
                    int nColumnCount = 0;
                    //记录每次读取的一行记录
                    string strLine = "";
                    //读取文件数据，写入头部列名及数据
                    using (FileStream fileStream = new FileStream(argFilePathName, FileMode.Open, FileAccess.Read))
                    {
                        OfficeFileDataReadTable FileDataTable = new OfficeFileDataReadTable();
                        StreamReader streamReader = new StreamReader(fileStream, Encoding.UTF8);
                        //逐行读取CSV中的数据
                        while ((strLine = streamReader.ReadLine()) != null)
                        {
                            //记录每行记录中的各字段内容（列名、数据）
                            string[] DataRowList = strLine?.Trim().Split(',');
                            if (!bIsColumnReader) { nColumnCount = DataRowList.Length; }
                            if (argIsExistsColumns && !bIsColumnReader)
                            {
                                bIsColumnReader = true;
                                for (int i = 0; i < nColumnCount; i++)
                                {
                                    FileDataTable.SheetDataTable.Columns.Add(new DataColumn(DataRowList[i]));
                                }
                            }
                            else
                            {
                                DataRow dataRow = FileDataTable.SheetDataTable.NewRow();
                                for (int Col = 0; Col < nColumnCount; Col++)
                                {
                                    if (Col <= (DataRowList.Length - 1))
                                    {
                                        dataRow[Col] = DataRowList[Col];
                                    }
                                }
                                FileDataTable.SheetDataTable.Rows.Add(dataRow);
                            }
                        }
                        ResultDataTable.Data.Add(FileDataTable);
                        streamReader.Close();
                        fileStream.Close();
                    }
                }
                catch (Exception ep)
                {
                    ResultDataTable.ResultCode = ResultStatus.Exception;
                    ResultDataTable.ResultMsg = "Exception Message：" + ep.Message;
                }
                finally
                {
                    swatch.Stop();
                    ResultDataTable.ResultMilliseconds = swatch.ElapsedMilliseconds;
                }
                return ResultDataTable;
            });
        }

        /// <summary>
        /// 写入列名和列值数据[多个相同表结构DataTable到CSV文件]
        /// </summary>
        /// <param name="argFilePathName">文件路径及csv文件名称</param>
        /// <param name="argDataTableList">数据表集合</param>
        /// <returns>true-保存成功，false-保存失败</returns>
        public Task<Result> WriteDataTableHead(string argFilePathName, List<DataTable> argDataTableList)
        {
            return Task.Run(() =>
            {
                Result result = new Result();
                if (string.IsNullOrWhiteSpace(argFilePathName)) { return new Result(ResultStatus.Failure); }
                if (argDataTableList == null || argDataTableList.Count <= 0) { return new Result(ResultStatus.Failure); }
                try
                {
                    DataTable DataTableColumn = argDataTableList.Where(x => x.Rows.Count > 0).FirstOrDefault();
                    //获取所有的列名集合，拼接字符串，写入csv文件列名表头
                    string strColumnNames = string.Join(",", DataTableColumn.Columns.Cast<DataColumn>().Select(dc => dc.ColumnName));
                    //检查创建文件，并写入头部列名
                    Task<Result> bResultTaskHead = WriteStreamFileHead(argFilePathName, true, strColumnNames);
                    Task.WaitAll(bResultTaskHead);
                    result = bResultTaskHead.Result;
                    if (result.ResultState)
                    {
                        //循环追加写入数据，有路径直接调用
                        foreach (DataTable dtCurrent in argDataTableList)
                        {
                            if (dtCurrent.Rows.Count <= 0) { continue; }
                            Task<Result> ResultTask = WriteStreamFile(argFilePathName, dtCurrent, false, false);
                            Task.WaitAll(ResultTask);
                            if (ResultTask.Result != null && !ResultTask.Result.ResultState) { result = ResultTask.Result; }
                        }
                    }
                }
                catch (Exception ep)
                {
                    result.ResultCode = ResultStatus.Exception;
                    result.ResultMsg = "Exception Message：" + ep.Message;
                }
                return result;
            });
        }
        /// <summary>
        /// 写入列名和列值数据[单DataTable到CSV文件]
        /// </summary>
        /// <param name="argFilePathName">文件路径及csv文件名称</param>
        /// <param name="argDataTable">数据表</param>
        /// <param name="argIsCreateFile">是否创建文件</param>
        /// <param name="argIsCreateColumns">是否创建数据列名</param>
        /// <returns>true-保存成功，false-保存失败</returns>
        public Task<Result> WriteDataTableHead(string argFilePathName, DataTable argDataTable, bool argIsCreateFile = true, bool argIsCreateColumns = true)
        {
            return Task.Run(() =>
            {
                Result result = new Result(ResultStatus.Failure);
                if (string.IsNullOrWhiteSpace(argFilePathName)) { return result; }
                if (argDataTable == null || argDataTable.Rows.Count <= 0) { return result; }
                Stopwatch swatch = new Stopwatch();
                swatch.Start();
                try
                {
                    Task<Result> ResultTask = WriteStreamFile(argFilePathName, argDataTable, argIsCreateFile, argIsCreateColumns);
                    Task.WaitAll(ResultTask);
                    result = ResultTask.Result;
                }
                catch (Exception ep)
                {
                    result.ResultCode = ResultStatus.Exception;
                    result.ResultMsg = "Exception Message：" + ep.Message;
                }
                finally
                {
                    swatch.Stop();
                    result.ResultMilliseconds = swatch.ElapsedMilliseconds;
                }
                return result;
            });
        }
        /// <summary>
        /// 写入列名和列值数据[多个行数据到CSV文件]
        /// </summary>
        /// <param name="argFilePathName">文件路径及csv文件名称</param>
        /// <param name="argDataModelList">数据模型对象集合</param>
        /// <returns>true-保存成功，false-保存失败</returns>
        public Task<Result> WriteDataModelHead(string argFilePathName, List<string> argDataModelList, bool argIsCreateFile = true)
        {
            return Task.Run(() =>
            {
                Result result = new Result(ResultStatus.Failure);
                if (string.IsNullOrWhiteSpace(argFilePathName)) { return result; }
                if (argDataModelList == null || argDataModelList.Count <= 0) { return result; }
                Stopwatch swatch = new Stopwatch();
                swatch.Start();
                try
                {
                    result.ResultCode = ResultStatus.Succeed;
                    //检查创建文件，并写入头部列名
                    Task<Result> bResultTaskHead = WriteStreamFileHead(argFilePathName, argIsCreateFile, null);
                    Task.WaitAll(bResultTaskHead);
                    if (bResultTaskHead != null && bResultTaskHead.Result != null) { result = bResultTaskHead.Result; }
                    if (!result.ResultState) { return result; }
                    Task<Result> bResultTaskWrite = WriteStreamFileData(argFilePathName, argDataModelList);
                    Task.WaitAll(bResultTaskWrite);
                    result = bResultTaskWrite.Result;
                    if (bResultTaskWrite != null && bResultTaskWrite.Result != null) { result = bResultTaskWrite.Result; }
                }
                catch (Exception ep)
                {
                    result.ResultCode = ResultStatus.Exception;
                    result.ResultMsg = "Exception Message：" + ep.Message;
                }
                finally
                {
                    swatch.Stop();
                    result.ResultMilliseconds = swatch.ElapsedMilliseconds;
                }
                return result;
            });

        }
        /// <summary>
        /// 写入列名和列值数据[多个行数据到CSV文件]
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="argFilePathName">文件路径及文件名称</param>
        /// <param name="argDataModelList">数据模型对象集合</param>
        /// <param name="argIsCreateFile">是否创建文件</param>
        /// <param name="argIsCreatePropertys">是否创建属性字段名称</param>
        /// <param name="argIsTypeName">是否创建类名称</param>
        /// <returns></returns>
        public Task<Result> WriteDataModelHead<T>(string argFilePathName, List<T> argDataModelList, bool argIsCreateFile = true, bool argIsCreatePropertys = true, bool argIsTypeName = false) where T : class, new()
        {
            return Task.Run(() =>
            {
                Result result = new Result(ResultStatus.Failure);
                if (string.IsNullOrWhiteSpace(argFilePathName)) { return result; }
                if (argDataModelList == null || argDataModelList.Count <= 0) { return result; }
                Stopwatch swatch = new Stopwatch();
                swatch.Start();
                try
                {
                    //获得反射的入口  
                    Type type = typeof(T);
                    //定义创建泛型的字段或属性
                    List<MemberInfo> MemberInfos = new List<MemberInfo>();
                    //把所有的public属性加入到集合 并添加DataTable的列  
                    Array.ForEach(type.GetFields(), p => { MemberInfos.Add(p); });
                    //把所有的public属性加入到集合 并添加DataTable的列  
                    Array.ForEach(type.GetProperties(), p => { MemberInfos.Add(p); });
                    if (MemberInfos == null || MemberInfos.Count <= 0) { return result; }
                    result.ResultCode = ResultStatus.Succeed;
                    //获取类型名称
                    string strTypeName = argIsTypeName ? type.Name : null;
                    //获取拼接的字段或属性字符串
                    string strMemberInfos = argIsCreatePropertys ? string.Join(Separator, MemberInfos.Select(v => v.Name)) : null;
                    //检查创建文件，并写入头部列名
                    Task<Result> bResultTaskHead = WriteStreamFileHead(argFilePathName, argIsCreateFile, null);
                    Task.WaitAll(bResultTaskHead);
                    if (bResultTaskHead != null && bResultTaskHead.Result != null) { result = bResultTaskHead.Result; }
                    if (!result.ResultState) { return result; }
                    //检查是否追加写入数据，必须文件已经存在直接写入
                    if (argDataModelList.Count > BatchSize)
                    {
                        int nTotalBatchNum = argDataModelList.Count % BatchSize == 0 ? argDataModelList.Count / BatchSize : (argDataModelList.Count / BatchSize) + 1;
                        for (int i = 0; i < nTotalBatchNum; i++)
                        {
                            //写入方式1：数据行集合形式追加写入
                            IEnumerable<T> QueryDataModels = argDataModelList.Skip((i) * BatchSize).Take(BatchSize);
                            Task<Result> bResultTaskWrite = WriteStreamFileData(argFilePathName, QueryDataModels, MemberInfos, (i <= 0 ? strMemberInfos : null), (i <= 0 ? strTypeName : null));
                            Task.WaitAll(bResultTaskWrite);
                            if (bResultTaskWrite != null && bResultTaskWrite.Result != null && !bResultTaskWrite.Result.ResultState) { result = bResultTaskWrite.Result; }
                        }
                    }
                    else
                    {
                        //写入方式2：数据表追加写入
                        Task<Result> bResultTaskWrite = WriteStreamFileData(argFilePathName, argDataModelList, MemberInfos, strMemberInfos, strTypeName);
                        Task.WaitAll(bResultTaskWrite);
                        if (bResultTaskWrite != null && bResultTaskWrite.Result != null) { result = bResultTaskWrite.Result; }
                    }
                }
                catch (Exception ep)
                {
                    result.ResultCode = ResultStatus.Exception;
                    result.ResultMsg = "Exception Message：" + ep.Message;
                }
                finally
                {
                    swatch.Stop();
                    result.ResultMilliseconds = swatch.ElapsedMilliseconds;
                }
                return result;
            });

        }


        /// <summary>
        /// 写入列名和列值数据[DataTable到CSV文件]
        /// </summary>
        /// <param name="argFilePathName">文件路径及csv文件名称</param>
        /// <param name="argDataTable">数据表</param>
        /// <param name="argIsCreateFile">是否创建文件</param>
        /// <param name="argIsCreateColumns">是否创建数据列名</param>
        /// <returns>true-保存成功，false-保存失败</returns>
        private Task<Result> WriteStreamFile(string argFilePathName, DataTable argDataTable, bool argIsCreateFile = true, bool argIsCreateColumns = true)
        {
            return Task.Run(() =>
            {
                Result result = new Result(ResultStatus.Failure);
                if (string.IsNullOrWhiteSpace(argFilePathName)) { return result; }
                if (argDataTable == null || argDataTable.Rows.Count <= 0) { return result; }
                //获取所有的列名集合，拼接字符串，写入csv文件列名表头
                string strColumnNames = argIsCreateColumns ? string.Join(",", argDataTable.Columns.Cast<DataColumn>().Select(dc => dc.ColumnName)) : null;
                //检查创建文件，并写入头部列名
                Task<Result> bResultTaskHead = WriteStreamFileHead(argFilePathName, argIsCreateFile, strColumnNames);
                Task.WaitAll(bResultTaskHead);
                if (bResultTaskHead != null && bResultTaskHead.Result != null) { result = bResultTaskHead.Result; }
                if (!result.ResultState) { return result; }
                //检查是否追加写入数据，必须文件已经存在直接写入
                if (argDataTable.Rows.Count > BatchSize)
                {
                    int nTotalBatchNum = argDataTable.Rows.Count % BatchSize == 0 ? argDataTable.Rows.Count / BatchSize : (argDataTable.Rows.Count / BatchSize) + 1;
                    for (int i = 0; i < nTotalBatchNum; i++)
                    {
                        //写入方式1：数据行集合形式追加写入
                        IEnumerable<DataRow> QueryDataRows = argDataTable.AsEnumerable().Skip((i) * BatchSize).Take(BatchSize);
                        Task<Result> bResultTaskWrite = WriteStreamFileData(argFilePathName, QueryDataRows);
                        Task.WaitAll(bResultTaskWrite);
                        ////写入方式2：数据表拷贝追加写入
                        //DataTable QueryDataTables = argDataTable.AsEnumerable().Skip((i) * BatchSize).Take(BatchSize).CopyToDataTable();
                        //Task<Result> bResultTaskWrite = WriteStreamFileData(argFilePathName, QueryDataTables);
                        if (bResultTaskWrite.Result != null && !bResultTaskWrite.Result.ResultState) { result = bResultTaskWrite.Result; }
                    }
                }
                else
                {
                    //写入方式2：数据表追加写入
                    Task<Result> bResultTaskWrite = WriteStreamFileData(argFilePathName, argDataTable);
                    Task.WaitAll(bResultTaskWrite);
                    result = bResultTaskWrite.Result;
                }
                return result;
            });
        }
        /// <summary>
        /// 写入分批追加列名,并创建文件
        /// </summary>
        /// <param name="argFilePathName">文件路径及文件名称</param>
        /// <param name="argColumnNames">列名/属性/字段集字符串</param>
        /// <returns>true-保存成功，false-保存失败</returns>
        private Task<Result> WriteStreamFileHead(string argFilePathName, bool argIsCreateFile = true, string argCreateColumnNames = null)
        {
            return Task.Run(() =>
            {
                if (!argIsCreateFile) { return new Result(); }
                Result TaskResult = new Result(ResultStatus.Failure);
                try
                {
                    if (string.IsNullOrWhiteSpace(argFilePathName)) { return TaskResult; }
                    //获取该文件所在的文件夹路径
                    string strFolderPath = Path.GetDirectoryName(argFilePathName);
                    //检查路径是否存在，不存在先创建
                    if (!Directory.Exists(strFolderPath)) { Directory.CreateDirectory(strFolderPath); }
                    //判断文件是否存在，并创建文件写入头部列名
                    if (!File.Exists(argFilePathName))
                    {
                        //写入头部列名
                        using (FileStream fileStream = new FileStream(argFilePathName, FileMode.Create, FileAccess.ReadWrite))
                        {
                            StreamWriter streamWriter = new StreamWriter(fileStream, Encoding.UTF8);
                            // 在csv末尾写入
                            streamWriter.BaseStream.Seek(0, SeekOrigin.End);
                            //判断检查是否添加数据列名, 写入csv文件表头
                            if (!string.IsNullOrWhiteSpace(argCreateColumnNames))
                            {
                                streamWriter.Write(argCreateColumnNames);
                                streamWriter.WriteLine("");
                            }
                            streamWriter.Flush();
                            streamWriter.Close();
                            fileStream.Close();
                        }
                    }
                    TaskResult.ResultCode = ResultStatus.Succeed;
                }
                catch (Exception ep)
                {
                    TaskResult.ResultCode = ResultStatus.Exception;
                    TaskResult.ResultMsg = "Exception Message：" + ep.Message;
                }
                return TaskResult;
            });
        }
        /// <summary>
        /// 写入分批追加数据,必须文件已经存在[DataTable到CSV文件]
        /// </summary>
        /// <param name="argFilePathName">文件路径及文件名称</param>
        /// <param name="argDataTable">数据表</param>
        /// <returns>true-保存成功，false-保存失败</returns>
        private Task<Result> WriteStreamFileData(string argFilePathName, DataTable argDataTable, bool argIsCreateColumns = false)
        {
            return Task.Run(() =>
            {
                Result TaskResult = new Result(ResultStatus.Failure);
                try
                {
                    //存储数据到文件当中，通过流方式
                    using (StreamWriter sw = new StreamWriter(argFilePathName, true, Encoding.UTF8))
                    {
                        if (argIsCreateColumns)
                        {
                            //获取所有的列名集合，拼接字符串，写入csv文件列名表头
                            sw.Write(string.Join(",", argDataTable.Columns.Cast<DataColumn>().Select(dc => dc.ColumnName)));
                            sw.WriteLine("");
                        }
                        for (int i = 0; i < argDataTable.Rows.Count; i++)
                        {
                            //argDataTable.Rows.Cast<DataRow>().Select(dr=>dr.)
                            for (int j = 0; j < argDataTable.Columns.Count; j++)
                            {
                                if (argDataTable.Columns[j].DataType == typeof(DateTime))
                                {
                                    sw.Write(Convert.ToDateTime(argDataTable.Rows[i][j]).ToString("yyyy/MM/dd HH:mm:ss.fff\t") + ",");
                                }
                                else
                                {
                                    sw.Write(argDataTable.Rows[i][j].ToString() + ",");
                                }
                            }
                            sw.WriteLine("");
                        }
                        sw.Flush();
                        sw.Close();
                        TaskResult.ResultCode = ResultStatus.Succeed;
                    }
                }
                catch (Exception ep)
                {
                    TaskResult.ResultCode = ResultStatus.Exception;
                    TaskResult.ResultMsg = "Exception Message：" + ep.Message;
                }
                return TaskResult;
            });
        }
        /// <summary>
        /// 写入分批追加数据,必须文件已经存在[DataRows到CSV文件]
        /// </summary>
        /// <param name="argFilePathName">文件路径及文件名称</param>
        /// <param name="argDataRows">数据行集合</param>
        /// <returns>true-保存成功，false-保存失败</returns>
        private Task<Result> WriteStreamFileData(string argFilePathName, IEnumerable<DataRow> argDataRows, bool argIsCreateColumns = false)
        {
            return Task.Run(() =>
            {
                Result TaskResult = new Result(ResultStatus.Failure);
                try
                {
                    if (argDataRows == null || argDataRows.Count() <= 0) { return TaskResult; }
                    //存储数据到文件当中，通过流方式
                    using (StreamWriter sw = new StreamWriter(argFilePathName, true, Encoding.UTF8))
                    {
                        foreach (DataRow QueryDataRow in argDataRows)
                        {
                            for (int j = 0; j < QueryDataRow.Table.Columns.Count; j++)
                            {
                                if (QueryDataRow.Table.Columns[j].DataType == typeof(DateTime))
                                {
                                    sw.Write(Convert.ToDateTime(QueryDataRow[j]).ToString("yyyy/MM/dd HH:mm:ss.fff\t") + ",");
                                }
                                else
                                {
                                    sw.Write(QueryDataRow[j].ToString() + ",");
                                }
                            }
                            sw.WriteLine("");
                        }
                        sw.Flush();
                        sw.Close();
                        TaskResult.ResultCode = ResultStatus.Succeed;
                    }
                }
                catch (Exception ep)
                {
                    TaskResult.ResultCode = ResultStatus.Exception;
                    TaskResult.ResultMsg = "Exception Message：" + ep.Message;
                }
                return TaskResult;
            });
        }
        /// <summary>
        /// 写入分批追加数据,必须文件已经存在[DataRows到CSV文件]
        /// </summary>
        /// <param name="argFilePathName">文件路径及文件名称</param>
        /// <param name="argDataRows">数据行集合</param>
        /// <returns>true-保存成功，false-保存失败</returns>
        private Task<Result> WriteStreamFileData<T>(string argFilePathName, IEnumerable<T> argDataModelList, List<MemberInfo> MemberInfos, string argCreateColumnNames = null, string argTypeName = null) where T : class, new()
        {
            return Task.Run(() =>
            {
                Result TaskResult = new Result(ResultStatus.Failure);
                try
                {
                    if (MemberInfos == null || MemberInfos.Count() <= 0) { return TaskResult; }
                    if (argDataModelList == null || argDataModelList.Count() <= 0) { return TaskResult; }
                    //存储数据到文件当中，通过流方式
                    using (StreamWriter sw = new StreamWriter(argFilePathName, true, Encoding.UTF8))
                    {
                        //判断检查是否添加类型名称, 写入csv文件表头
                        if (!string.IsNullOrWhiteSpace(argTypeName))
                        {
                            sw.Write(argTypeName);
                            sw.WriteLine("");
                        }
                        //判断检查是否添加数据列名, 写入csv文件表头
                        if (!string.IsNullOrWhiteSpace(argCreateColumnNames))
                        {
                            sw.Write(argCreateColumnNames);
                            sw.WriteLine("");
                        }
                        foreach (var item in argDataModelList)
                        {
                            //拼接对象数据值,调用ToTypeValue扩展方法
                            string strDatas = string.Join(Separator, MemberInfos.Select((dm) =>
                            {
                                var resultVal = item.ToTypeValue(dm);
                                Type type = null;
                                if (dm is PropertyInfo) { type = (dm as PropertyInfo).PropertyType; }
                                else if (dm is FieldInfo) { type = (dm as FieldInfo).FieldType; }

                                if (type != null && type == typeof(DateTime))
                                {
                                    resultVal = Convert.ToDateTime(resultVal).ToString("yyyy/MM/dd HH:mm:ss.fff\t");
                                }
                                return resultVal;
                            }));
                            sw.Write(strDatas);
                            sw.WriteLine("");
                        }
                        sw.Flush();
                        sw.Close();
                        TaskResult.ResultCode = ResultStatus.Succeed;
                    }
                }
                catch (Exception ep)
                {
                    TaskResult.ResultCode = ResultStatus.Exception;
                    TaskResult.ResultMsg = "Exception Message：" + ep.Message;
                }
                return TaskResult;
            });
        }
        /// <summary>
        /// 写入分批追加数据,必须文件已经存在[DataItems到CSV文件]
        /// </summary>
        /// <param name="argFilePathName">文件路径及文件名称</param>
        /// <param name="argDataModelList">数据模型对象集合</param>
        /// <returns>true-保存成功，false-保存失败</returns>
        private Task<Result> WriteStreamFileData(string argFilePathName, IEnumerable<string> argDataModelList)
        {
            return Task.Run(() =>
            {
                Result TaskResult = new Result(ResultStatus.Failure);
                try
                {
                    if (argDataModelList == null || argDataModelList.Count() <= 0) { return TaskResult; }
                    //存储数据到文件当中，通过流方式
                    using (StreamWriter sw = new StreamWriter(argFilePathName, true, Encoding.UTF8))
                    {
                        foreach (var item in argDataModelList)
                        {
                            sw.Write(item);
                            sw.WriteLine("");
                        }
                        sw.Flush();
                        sw.Close();
                        TaskResult.ResultCode = ResultStatus.Succeed;
                    }
                }
                catch (Exception ep)
                {
                    TaskResult.ResultCode = ResultStatus.Exception;
                    TaskResult.ResultMsg = "Exception Message：" + ep.Message;
                }
                return TaskResult;
            });
        }
    }
}
